<?php

class Image {

	protected $png_quality;

	protected $jpg_quality;

	function __construct( ) {

		// Validar la existencia de GD
		if( !function_exists( 'gd_info' ) ) {
			throw new ImageException( 'Librería GD no disponible', 1 );
		}
		else {
			$this->png_quality = 9;
			$this->jpg_quality = 90;
		}
	}

	function resize( $input_file, $output_file, $max_w, $max_h ) {

		$resized = FALSE;
		
		// Verificar el archivo original
		if( !is_file( $input_file ) ) {
			throw new ImageException( 'Archivo de imagen "' . $input_file . ' no existe.', 2 );
		}
	
		// Obtener datos de la imagen original
		$img_info = @getimagesize( $input_file );
		if( $img_info == FALSE ) {
			throw new ImageException( 'Error al obtener información del archivo "' . $input_file . '"', 3 );
		}
		
		/*
		 * Calcular las nuevas dimensiones de la imagen final.
		 */
		$img_new_w = $img_src_w = $img_info[0];
		$img_new_h = $img_new_src_h = $img_src_h = $img_info[1];
		
		// Calcular en base al ancho
		if( $img_new_w > $max_w ) {
			$img_new_w = $max_w;
			$img_new_src_h = $img_new_h = round( $img_new_h / ($img_src_w / $img_new_w) );
		}
		
		// Calcular en base al alto
		if( $img_new_h > $max_h ) {
			$img_new_h = $max_h;
			$img_new_w = round( $img_new_w / ($img_new_src_h / $img_new_h) );
		}
				
		// Realizar redimensionado solo si es necesario
		if( $img_new_w != $img_info[0] || $img_new_h != $img_info[1] ){

			$resized = TRUE;
			
			/*
			 * Leer imagen original
			 */
			switch( $img_info[2] ) {
				case IMAGETYPE_GIF:
					$img_src = @imagecreatefromgif( $input_file );
					break;
				case IMAGETYPE_PNG:
					$img_src = @imagecreatefrompng( $input_file );
					break;
				case IMAGETYPE_JPEG:
					$img_src = @imagecreatefromjpeg( $input_file );
					break;
				default:
					throw new ImageException( 'La imagen "' . $input_file . '" no esta soportada.', 4 );
					break;
			}
			
			if( $img_src == FALSE ) {
				throw new ImageException( 'Error al crear la imagen desde el archivo original', 5 );
			}
				
			/*
			 * Crear imagen destino
			 */
			$img_dst = @imagecreatetruecolor( $img_new_w, $img_new_h );
			
			if( $img_dst == FALSE ) {
				throw new ImageException( 'Error al crear la imagen destino', 6 );
			}
				
			/*
			 * Copiar mapa de bits de la imagen original en la imagen destino
			 * con las proporciones calculadas. 
			 */
			$copy_result = @imagecopyresampled( $img_dst, $img_src, 0, 0, 0, 0, $img_new_w, $img_new_h, $img_info[0], $img_info[1] );
			
			if( $copy_result == FALSE ) {
				@imagedestroy( $img_dst );
				throw new ImageException( 'Error al redimensionar la imagen', 7 );
			}
			
			/*
			 * Guardar archivo de imagen final
			 */
			switch( $img_info[2] ) {
				case IMAGETYPE_GIF:
					$output_result = @imagegif( $img_dst, $output_file );
					break;
				case IMAGETYPE_PNG:
					$output_result = @imagepng( $img_dst, $output_file, $this->png_quality );
					break;
				case IMAGETYPE_JPEG:
					$output_result = @imagejpeg( $img_dst, $output_file, $this->jpg_quality );
					break;
			}
			
			// Liberar memoria
			@imagedestroy( $img_src );
			@imagedestroy( $img_dst );
			
			if( $output_result == FALSE ) {
				throw new ImageException( 'Error al crear la imagen final', 8 );
			}
			
		} // if( $img_new_w != $img_info[0] || $img_new_h != $img_info[1] )
		
		return $resized;
	}

	public function getPngQuality( ) {

		return $this->png_quality;
	}

	public function setPngQuality( $png_quality ) {

		$this->png_quality = $png_quality;
	}

	public function getJpgQuality( ) {

		return $this->jpg_quality;
	}

	public function setJpgQuality( $jpg_quality ) {

		$this->jpg_quality = $jpg_quality;
	}

}